home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / awe2-0_1.lha / awe2-0.1 / Src / Facility.cc < prev    next >
C/C++ Source or Header  |  1990-07-09  |  7KB  |  357 lines

  1. // This may look like C code, but it is really -*- C++ -*-
  2. // 
  3. // Copyright (C) 1988 University of Illinois, Urbana, Illinois
  4. // Copyright (C) 1989 University of Colorado, Boulder, Colorado
  5. // Copyright (C) 1990 University of Colorado, Boulder, Colorado
  6. //
  7. // written by Dirk Grunwald (grunwald@foobar.colorado.edu)
  8. //
  9. #include "SimulationMultiplexor.h"
  10. #include "Facility.h"
  11. #include "FifoScheduler.h"
  12. #include "Thread.h"
  13. #include "assert.h"
  14. #include <math.h>
  15.  
  16. Facility::Facility(int xservers, ThreadContainer *xscheduler)
  17.     : (xservers,xscheduler)
  18. {
  19.     //
  20.     //    Can't use reset because we need to set up service times with
  21.     // NullTime value.
  22.     //
  23.     servers = xservers;
  24.     totalServiceTime = 0.0;
  25.  
  26.     pTotalReserves = 0;
  27.     pTotalFailures = 0;
  28.  
  29.     pTotalDelay = 0.0;
  30.     serviceStarted = CurrentSimulatedTime;
  31.     
  32.     if (servers == 1) {
  33.     whenServiced.single = NullTime;
  34.     } else {
  35.     whenServiced.many = new double[servers];
  36.     for (int i = 0; i < servers; i++) {
  37.         whenServiced.many[i] = NullTime;
  38.     }
  39.     }
  40. }
  41.  
  42. //
  43. //    To reset a facility, we assume that there has been no service
  44. //    so far (totalServiceTime = 0) and then set the beginning of
  45. //    outstanding service intervals to be now.
  46. //
  47. //    Thus, right after being reset, a facility has a utilization of zero.
  48. //
  49. void
  50. Facility::reset()
  51. {
  52.     dataLock.reserve();
  53.  
  54.     double now = CurrentSimulatedTime;
  55.     totalServiceTime = 0.0;
  56.  
  57.     pTotalReserves = 0;
  58.     pTotalFailures = 0;
  59.  
  60.     pTotalDelay = 0.0;
  61.     serviceStarted = now;
  62.     if (servers == 1) {
  63.     if (whenServiced.single != NullTime) {
  64.         whenServiced.single = now;
  65.     }
  66.     } else {
  67.     for (int i = 0; i < servers; i++) {
  68.         if (whenServiced.many[i] != NullTime) {
  69.         whenServiced.many[i] = now;
  70.         }
  71.     }
  72.     }
  73.     dataLock.release();
  74. }
  75.  
  76. Facility::~Facility()
  77. {
  78.     dataLock.reserve();
  79.  
  80.     int error = 0;
  81.     if (servers == 1) {
  82.     error = (whenServiced.single != NullTime);
  83.     } else {
  84.     for(int i = 0; i < servers; i++) {
  85.         error |= (whenServiced.many[i] != NullTime);
  86.     }
  87.     }
  88.  
  89.     if (error) {
  90.     cerr << "[Facility:~Facility]";
  91.     cerr << "Attempted to de-allocate reserved facility\n";
  92. //    cerr << *this;
  93.     exit(1);
  94.     }
  95.  
  96.     dataLock.release();
  97. }
  98.  
  99. void Facility::commonReserve(double delayTime)
  100. {
  101.  
  102.     dataLock.reserve();
  103.     
  104.     pTotalReserves++;
  105.     pTotalDelay += delayTime;
  106.  
  107.     if (servers == 1) {
  108.     if (whenServiced.single == NullTime) {
  109.         whenServiced.single = CurrentSimulatedTime;
  110.         dataLock.release();
  111.         return;
  112.     }
  113.     } else {
  114.     for (int i = 0; i < servers; i++) {
  115.         if (whenServiced.many[i] == NullTime) {
  116.         whenServiced.many[i] = CurrentSimulatedTime;
  117.         dataLock.release();
  118.         return;
  119.         }
  120.     }
  121.     }
  122.  
  123.     dataLock.release();    // need to release so reportErrorState works
  124.  
  125.     reportErrorState(cerr);
  126.     assert2(FALSE, "[Facility] state error with facility semaphore");
  127. }
  128.  
  129. void Facility::reserve()
  130. {
  131.     double startedReserve = CurrentSimulatedTime;
  132.     Semaphore::reserve();
  133.     commonReserve( CurrentSimulatedTime - startedReserve );
  134. }
  135.  
  136. void
  137. Facility::use(double howLong)
  138. {
  139.     reserve();
  140.     hold(howLong);
  141.     release();
  142. }
  143.  
  144. bool Facility::reserveNoBlock()
  145. {
  146.     if (Semaphore::reserveNoBlock()) {
  147.     commonReserve(0.0);    // commonReserve will bumb pTotalReserves
  148.     return(TRUE);
  149.     } else {
  150.     dataLock.reserve();
  151.  
  152.     pTotalFailures++;
  153.  
  154.     dataLock.release();
  155.  
  156.     return(FALSE);
  157.     }
  158. }
  159.  
  160. void Facility::release()
  161. {
  162.     dataLock.reserve();
  163.  
  164.     double now = CurrentSimulatedTime;
  165.     bool error = 0;
  166.     
  167.     if (servers == 1) {
  168.     if (whenServiced.single != NullTime) {
  169.         totalServiceTime += (now - whenServiced.single);
  170.         whenServiced.single = NullTime;
  171.     } else {
  172.         error = 1;
  173.     }
  174.     } else {
  175.     error = 1;
  176.     for (int i = 0; i < servers; i++) {
  177.         if (whenServiced.many[i] != NullTime) {
  178.         totalServiceTime += (now - whenServiced.many[i]);
  179.         whenServiced.many[i] = NullTime;
  180.         error = 0;
  181.         break;
  182.         }
  183.     }
  184.     }
  185.  
  186.     dataLock.release();
  187.     
  188.     if (error) {
  189.     cerr << "[Facility::release] ";
  190.     cerr << "Attempt to release un-reserved facility\n";
  191. //    cerr << *this;
  192.     exit(1);
  193.     }
  194.     Semaphore::release();
  195. }
  196.  
  197. double Facility::utilization()
  198. {
  199.     //
  200.     //    To compute utilization, we sum the outstanding request times,
  201.     //    add in the current total service time, and divide this by
  202.     //    the number of facilities & the number servers.
  203.     // 
  204.  
  205.     dataLock.reserve();
  206.     
  207.     double totalTime = totalServiceTime;
  208.     double now = CurrentSimulatedTime;
  209.     
  210.     if (servers == 1) {
  211.     if (whenServiced.single != NullTime) {
  212.         totalTime += (now - whenServiced.single);
  213.     }
  214.     } else {
  215.     for (int i = 0; i < servers; i++) {
  216.         if (whenServiced.many[i] != NullTime) {
  217.         totalTime += (now - whenServiced.many[i]);
  218.         }
  219.     }
  220.     }
  221.     
  222.     if (now == serviceStarted) {
  223.     totalTime = 0;
  224.     } else {
  225.     totalTime /= (servers * (now - serviceStarted));
  226.     }
  227.     dataLock.release();
  228.     return(totalTime);
  229. }
  230.  
  231. double
  232. Facility::perceivedUtilization()
  233. {
  234.     dataLock.reserve();
  235.     double util = 0;
  236.     long pTotal = pTotalReserves + pTotalFailures;
  237.     if ( pTotal >0 ) {
  238.     util = pTotalFailures;
  239.     util /= pTotal;
  240.     }
  241.     dataLock.release();
  242.     return( util );
  243. }
  244.  
  245. long
  246. Facility::totalAttempts()
  247. {
  248.     dataLock.reserve();
  249.     int res = pTotalReserves + pTotalFailures;
  250.     dataLock.release();
  251.     return(res);
  252. }
  253.  
  254. long
  255. Facility::totalReserves()
  256. {
  257.     dataLock.reserve();
  258.     int res = pTotalReserves;
  259.     dataLock.release();
  260.     return(res);
  261. }
  262.  
  263. long
  264. Facility::totalFailures()
  265. {
  266.     dataLock.reserve();
  267.     int res = pTotalFailures;
  268.     dataLock.release();
  269.     return(res);
  270. }
  271.  
  272. double
  273. Facility::totalDelay()
  274. {
  275.     return(pTotalDelay);
  276. }
  277.  
  278. double
  279. Facility::meanDelay()
  280. {
  281.     if (pTotalReserves > 0) {
  282.     return( pTotalDelay / pTotalReserves);
  283.     } else {
  284.     return( 0.0 );
  285.     }
  286. }
  287.  
  288. unsigned Facility::queueLength()
  289. {
  290.     return(Semaphore::size());
  291. }
  292.  
  293. unsigned Facility::activeServers()
  294. {
  295.     dataLock.reserve();
  296.  
  297.     int outStanding = 0;
  298.     if (servers == 1) {
  299.     if (whenServiced.single != NullTime) {
  300.         outStanding++;
  301.     }
  302.     } else {
  303.     for (int i = 0; i < servers; i++ ){
  304.         if (whenServiced.many[i] != NullTime) {
  305.         outStanding++;
  306.         }
  307.     }
  308.     }
  309.     dataLock.release();
  310.  
  311.     return(outStanding);
  312. }
  313.  
  314. unsigned Facility::size()
  315. {
  316.     return(queueLength() + activeServers());
  317. }
  318.  
  319. bool Facility::isEmpty()
  320. {
  321.     return(size() == 0);
  322. }
  323.  
  324. #ifdef UNDEF
  325. void Facility::classPrintOn(ostream &out)
  326. {
  327.     out << "Facility with " << activeServers() << " active servers and "
  328.     << queueLength() << " queued requests";
  329. }
  330. #endif
  331.  
  332. void Facility::reportErrorState(ostream &out)
  333. {
  334. //    out << *this << "\n";
  335.     out << "Serviced started at " << serviceStarted
  336.     << " with a total service time of " << totalServiceTime << "\n";
  337.     if (servers == 1) {
  338.     out << "Server 1 ";
  339.     if (whenServiced.single == NullTime) {
  340.         out << " is idle\n";
  341.     } else {
  342.         out << " started serving at " << whenServiced.single << "\n";
  343.     }
  344.     } else {
  345.     for (int i = 0; i < servers; i++) {
  346.         out << "Server " << i ;
  347.         if (whenServiced.many[i] == NullTime) {
  348.         out << " is idle\n";
  349.         } else {
  350.         out << " started serving at " << whenServiced.many[i] << "\n";
  351.         }
  352.     }
  353.     }
  354.     out << "State of facility semaphore is:\n";
  355. //    Semaphore::classPrintOn(out);
  356. }
  357.